package com.itheima.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

//通知类，告诉spring在增强的前后需要做什么事
@Component
@Aspect  //代替：<aop:aspect ref="advice">，该类即是一个通知类也是一个切面类
public class Advice {
    //定义切入点表达式的方法,方法体不需要写任何内容，方法名就是切入点的id
//<aop:pointcut id="pt" expression="execution( * com.itheima.service.StudentService.*(..))"/>
    @Pointcut("execution(* com.itheima.service.StudentService.findAll(..))")
    public void pt(){}
    @Pointcut("execution(* com.itheima.service.StudentService.delete(..))")
    public void pt2(){}


    public void before(){
        //前置通知：开启事务
        System.out.println("前置通知：开启事务");
    }
    public void afterReturn(){
        //后置通知：提交事务
        System.out.println("后置通知：提交事务");
    }
    public void afterThrowable(Throwable throwable){
        //异常通知：回滚事务
        System.out.println("异常通知：回滚事务"+throwable.getMessage());
    }
    public void after(){
        //最终通知：释放资源
        System.out.println("最终通知：释放资源");
    }

    @Around("pt()||pt2()")
    public Object around(ProceedingJoinPoint pjp){
        Object result = null;
        try {
             before();
             result = pjp.proceed();
           afterReturn();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            afterThrowable(throwable);
        }finally {
            after();
        }
        return result;
    }
}
